import sys
from typing import *
from dataclasses import dataclass
from enum import Enum,auto
from pathlib import Path
import ramda as R
import ux as Ux
from tasks import Tasks
import lu_img

class Const:
    FPS = 25
    IMG_FILEEXTS = ['jpg', 'jpeg', 'png', 'bmp', 'webp', 'tiff', 'tif']

@dataclass
class LuImgStatus(Enum):
    IDLE = auto()
    CHECKING = auto()
    DONE = auto()
class LuImg:
    def __init__(me, sys) -> None:
        me.__lu = lu_img.LuImg()
        me.__tasks = Tasks()
        me.__sys = sys
        me.__status = LuImgStatus.IDLE
        me.__last_groups = []

    def on_done(me, ux:Ux.UxRoot) -> None:
        me.__last_groups = me.__lu.result_groups()
        me.__status = LuImgStatus.DONE
        me.on_refresh_result(ux)

    def on_frame(me, ux:Ux.UxRoot) -> None:
        if LuImgStatus.CHECKING == me.__status:
            n_all = me.__tasks.all_nums()
            n_has_done = me.__tasks.has_done_nums()
            ux.send("img/set-status", f"Checking: {n_has_done} / {n_all}")
        elif LuImgStatus.DONE == me.__status:
            n_same_all = R.reduce((lambda a,b:a+len(b)), 0, me.__last_groups)
            ux.send("img/set-status", f"Done: Same-Numbers [Group {len(me.__last_groups)}] [All {n_same_all}]")
        else:
            ux.send("img/set-status", "No Task")

    def on_start(me, ux:Ux.UxRoot) -> None:
        if not me.__tasks.has_run():
            if LuImgStatus.DONE == me.__status:
                me.__lu.reset()
                me.__tasks = Tasks()
            me.__status = LuImgStatus.CHECKING
            dirs = [Path(a) for a in me.__sys.selected_dirs()]
            ux.send("img/clear-result")
            me.__tasks.start(me.__lu, Const.IMG_FILEEXTS, dirs, (lambda:me.on_done(ux)))

    def on_tap(me, ux:Ux.UxRoot, data) -> None:
        ux.send("img/dialog-result", data)

    def on_refresh_result(me, ux:Ux.UxRoot) -> None:
        ux.send("img/clear-result")
        groups = list(me.__last_groups)
        groups = R.map(R.filter((lambda path:Path(path).is_file())), groups)
        groups = R.filter((lambda a:(len(a) > 1)), groups)
        for group in groups:
            n_paths = len(group)
            icon_path = group[0]
            title = f"[{n_paths}] {icon_path}"
            ux.send("img/add-result", icon_path, title, group)
        me.__last_groups = groups

class System(Ux.IO):
    def __init__(me, ux:Ux.UxRoot):
        me.__ux = ux
        me.__lu_img = LuImg(me)
        me.__selected_dirs = []

    def selected_dirs(me) -> List[str]: return me.__selected_dirs

    def on_ready(me) -> None:
        pass

    def on_frame(me) -> None:
        me.__lu_img.on_frame(me.__ux)

    def on_selected_dirs(me, dirs:List[str]) -> None: me.__selected_dirs = dirs

    def on_img_check_start(me) -> None: me.__lu_img.on_start(me.__ux)
    def on_img_result_tap(me, data) -> None: me.__lu_img.on_tap(me.__ux, data)
    def on_img_refresh_result(me) -> None: me.__lu_img.on_refresh_result(me.__ux)

def main(args:[str]):
    ux = Ux.Ux(Const.FPS)
    ux.start(System(ux))
try:
    main(sys.argv[1:])
finally:
    pass
